#include<stdio.h>

#include<stdlib.h>

#define INIT_SIZE 100  /*线性表存储空间的初始分配量*/
#define INCREMENT 10  /*线性表存储空间的分配增量*/
//student结构体定义
typedef struct
{
	char sno[15];     //学号 
	char sname[15];   //姓名 
	char sex[6];   		//性别 
	int score;		//专业 
}student;


//SqList结构体类型定义


typedef student ElemType; /*定义元素类型为student*/
typedef struct {
	ElemType *elem;    /*存储空间的基地址*/
	int length;         /*当前长度*/
	int listsize;   	  /*当前分配的存储容量(以sizeof(ElemType)为单位)*/
}SqList;

//顺序表的初始化


int InitList_Sq(SqList *L)
/*初始化顺序表，成功返回1，失败返回0*/
{
	L->elem = (ElemType *)malloc(INIT_SIZE * sizeof(ElemType));
	if (!L->elem) return 0;   /*初始化失败*/
	L->length = 0;
	L->listsize = INIT_SIZE;
	return 1;                /*初始化成功*/
}


//顺序表元素浏览
int ListDisplay_Sq(SqList*L)
{
	int i;
	if (L->length == 0)
	{
		printf("当前为空表!\n");
		return 0;
	}
	printf("**显示所有学生信息**\n");
	printf("学号：      姓名：        课程名：       课程成绩：     \n");
	for (i = 0; i<L->length; i++)
	{
		printf("%-11s%-11s%-12s%-11d\n", L->elem[i].sno, L->elem[i].sname, L->elem[i].sex, L->elem[i].score);
	}
	return 1;
}


//顺序表插入元素
int ListInsert_Sq(SqList *L, int i, ElemType e)
/*在顺序表L的第i个位置之前插入新的元素e，若插入成功则返回1，否则返回0*/
{
	int j;
	ElemType *newbase;
	if (i<0 || i>L->length)   return 0;     	/*插入位置不合法，插入失败*/
	if (L->length >= L->listsize)            	/*当前存储空间已满，增加分配*/
	{
		newbase = (ElemType *)realloc(L->elem, (L->listsize + INCREMENT) * sizeof(ElemType));
		if (!newbase) return 0;  /*存储分配失败，插入失败*/
		L->elem = newbase;
		L->listsize += INCREMENT;
	}
	for (j = L->length - 1; j >= i; j--)
		L->elem[j + 1] = L->elem[j]; 	/*插入位置及之后的元素从后开始向后移动*/
	L->elem[i] = e;                   		/*插入e*/
	++L->length;                    	/*表长增1*/
	return 1;                     		/*插入成功*/
}



//按位序删除
int ListDelete_Sq(SqList*L, int i, ElemType*e)
/*在顺序表L中删除第i个元素，并用e返回其值，成功返回1，失败返回0*/
{
	int j;
	if (i<0 || i>L->length - 1)return 0;       /*i值不合法，删除失败* /
											   *e=L->elem[i];                        /*将被删除元素的值赋给e*/
	for (j = i + 1; j <= L->length - 1; j++)
		L->elem[j - 1] = L->elem[j];           /*被删除元素之后的元素从前开始向前移动*/
	--L->length;
	return 1;            /*删除成功*/
}

/*在顺序表中顺序查找关键字等于key的数据元素。若找到，则返回该元素在表中的索引，否则为-1*/

int Search_Seq(SqList ST, char key[8])
{
	int i;
	strcpy(ST.elem[ST.length].sname, key);    //哨兵
	for (i = 0; strcmp(ST.elem[i].sname, key) != 0; ++i);     //从前往后找
	if (i<ST.length)
		return i;
	else
		return -1;
}


//按成绩或学号排序
int  InsertSort(SqList L, ElemType e)
{
	int i, j;
	for (i = 1; i <= L.length - 1; i++)
	{
		L.elem[L.length] = L.elem[i];
		for (j = i - 1; j >= 0; j--)
		{
			if (L.elem[j].score > L.elem[L.length].score)
			{
				L.elem[j + 1] = L.elem[j];
			}
			else break;
		}
		L.elem[j + 1] = L.elem[L.length];
	}
}


	//#include<windows.h>
	/*********************************/
	/*       输 出 主 控 菜 单       */
	/*********************************/
	int menu_select()
	{
		int ch;


		system("cls");
		printf("\n\t**************学生信息管理系统******************\n");
		printf("\n\t&\t\t1.浏览学生信息\t\t\t&\t\n");
		printf("\n\t&\t\t2.插入学生信息\t\t\t&\t\n");
		printf("\n\t&\t\t3.删除学生信息\t\t\t&\t\n");
		printf("\n\t&\t\t4.查找学生信息\t\t\t&\t\n");
		printf("\n\t&\t\t5.学生信息修改\t\t\t&\t\n");
		printf("\n\t&\t\t6.学生信息排序\t\t\t&\t\n");
		printf("\n\t&\t\t0.退出系统\t\t\t&\t\t\t\t\t\n");
		printf("\n\t***********************************************\n");
		printf("\n\t\t请选择您要运行的功能选项(0—6):    ");
		scanf("%d", &ch);
		return ch;
	}
	/*定义主函数*/
	main()
	{
		int p = 1, m, i;
		int loc;
		char key[4];
		ElemType x;
		SqList SL;
		InitList_Sq(&SL);

		while (1)
		{
			switch (menu_select())
			{
			case 1: printf("\n此功能可以浏览学生信息\n\n"); system("pause");
				ListDisplay_Sq(&SL);
				printf("表中元素个数共%d个\n", SL.length);
				system("pause");
				break;
			case 2:printf("\n此功能可以插入学生信息\n\n"); system("pause");
				p = 1;
				while (p == 1)
				{
					printf("请输入插入学生的信息：\n");
					printf("请输入插入学生学号：");           scanf("%s", x.sno);
					printf("请输入插入学生的姓名：");          scanf("%s", x.sname);
					printf("请输入插入学生的性别：");         scanf("%s", x.sex);
					printf("请输入插入学生的成绩：");           scanf("%d", &x.score);
					ListInsert_Sq(&SL, SL.length, x);
					printf("是否继续输入（1表示继续插入，0表示终止插入）");
					scanf("%d", &p);
				}
				printf("终止信息的插入\n");
				ListDisplay_Sq(&SL);
				system("pause");
				break;

			case 3:printf("\n此功能可以删除学生信息\n\n");
			 
				p = 1;
				while (p == 1)
				{
					printf("请输入要删除学生的位序（0-%d）", SL.length - 1);
					scanf("%d", &loc);
					ListDelete_Sq(&SL, loc, &x);
					printf("删除后表中元素有: \n");
					ListDisplay_Sq(&SL);
					printf("是否继续删除（1表示继续删除，0表示终止删除）");
					scanf("%d", &p);
				}
				ListDisplay_Sq(&SL);
				system("pause");
				break;

			case 4:printf("\n此功能可以查找学生信息\n\n");
				printf("请输入待查学生的姓名：");
				scanf("%s", key);
			        loc = Search_Seq(SL, key);                //调用Search函数 
				if (loc != -1)
					printf("%-11s%-11s%-11s%-11d\n", SL.elem[loc].sno, SL.elem[loc].sname, SL.elem[loc].sex,                                              SL.elem[loc].score);
				else
					printf("查找有误，无该同学\n");
				system("pause"); break;
			case 5:printf("\n此功能可以修改学生信息\n\n");
			printf("要查找的学生的姓名为:"); scanf("%s", key);
				loc = Search_Seq(SL, key);
				if (loc == -1)
					printf("无该学生信息\n");
			{printf("是否修改学生的信息(修改输入1、不修改输入-1结束本操作):");
				scanf("%d", &i);
				if (i == 1)
				{
					printf("   请输入修改后学生信息  \n");
					printf("请输入修改后学生学号:");            scanf("%s", SL.elem[loc].sno);
					printf("请输入修改后学生的姓名:");          scanf("%s", SL.elem[loc].sname);
					printf("请输入修改后学生的性别:");          scanf("%s", SL.elem[loc].sex);
					printf("请输入修改后学生的成绩:");          scanf("%d", &SL.elem[loc].score);
					printf("    \n\n进入1模块可以查看修改后的信息\n"); 
				}
				    
				else
					ListDisplay_Sq(&SL);}
					system("pause"); break;
			case 6: printf("\n此功能可以排序学生信息\n\n");
				InsertSort(SL,SL.elem[loc]);
				ListDisplay_Sq(&SL);
				system("pause"); break;
			case 0:printf("\n谢谢使用本系统，再见！！^_^\n\n"); system("pause"); exit(0);
			default:printf("\n无效输入,请重新选择\n\n");	 system("pause"); break;
			}


		}
	}